home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / mac_io.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  20KB  |  1,144 lines

  1. /* OS- and machine-dependent stuff for Mac  */
  2.  
  3. /*mac_io.c
  4.  *    Routines for Macintosh IO and file stuff
  5.  */
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "internet.h"
  10. #include "iface.h"
  11. #include "mac.h"
  12. #include "cmdparse.h"
  13.  
  14. #include "DeviceMgr.h"
  15. #include "WindowMgr.h"
  16. #include "EventMgr.h"
  17. #include "SerialDvr.h"
  18. #include "HFS.h"
  19. #include <time.h>
  20. extern long timezone;
  21. extern errno;
  22.  
  23. struct Store_input Store_input[ASY_MAX];
  24.  
  25. struct asy asy[ASY_MAX];
  26.  
  27. static ioParam    MacSer;
  28.  
  29. struct interface *ifaces;
  30. static struct RemoveIt {
  31.     struct RemoveIt *next;
  32.     char *name_ptr;
  33. } *Head;
  34.  
  35.  
  36. /* Called at startup time to set up console I/O, memory heap */
  37. ioinit()
  38. {
  39.     timezone = 60*60+1;
  40.     tzname[0] = "CST";
  41.     tzname[1] = "CST";
  42.     Click_On(0);
  43.     Head = malloc(sizeof (struct RemoveIt));
  44.     Head->next = NULL;
  45.     Head->name_ptr = NULL;
  46.     return(0);
  47. }
  48. /* Called just before exiting to restore console state */
  49. iostop()
  50. {
  51.     int i;
  52.     struct RemoveIt *rptr;
  53.     
  54.     while(ifaces != NULLIF){
  55.         if(ifaces->stop != NULLFP)
  56.             (*ifaces->stop)(ifaces);
  57.         ifaces = ifaces->next;
  58.     }
  59.     /*
  60.      * I want to close down all the files and then remove the (possibly still existing) files
  61.      * because the MAC will not allow the file to be removed when it still has an open file
  62.      * descriptor
  63.      */
  64.      
  65.     for( i = 3; i < _NFILE; i++)
  66.     {
  67.         close(i);
  68.     }
  69.     (void)unlink("dir.temp");
  70.     rptr = Head;
  71.     while( rptr->next != NULL)
  72.     {
  73.         if ( rptr->name_ptr != NULL)
  74.             unlink(rptr->name_ptr);
  75.         rptr = rptr->next;
  76.     }    
  77. }
  78.  
  79. /* Initialize asynch port "dev" */
  80.  
  81. int slipisopen = 0;
  82. int iref;
  83. int oref;
  84.  
  85. char Recv_buf[MAX_STORE];
  86. char Send_buf[MAX_STORE];
  87.  
  88. int
  89. asy_init(dev,arg1,arg2,bufsize)
  90. int16 dev;
  91. char *arg1,*arg2;
  92. unsigned bufsize;
  93. {
  94.     register struct asy *ap;
  95.     register struct interface *if_asy;
  96.     extern struct interface *ifaces;
  97.     char ser_name[255];
  98.     struct Store_input *store;
  99.     
  100.     OsErr e;
  101.     ap = &asy[dev];
  102.  
  103.     ap->tty = malloc(strlen(arg2)+1);
  104.     strcpy(ap->tty, arg2);
  105.  
  106. #ifdef DEBUG
  107.     printf("asy_init: as->tty = %s, dev = %d\n", ap->tty, dev); 
  108. #endif
  109.     if ( ap == NULL)
  110.     {
  111.         return(-1);
  112.     }
  113.     
  114.     switch ( ap->tty[0] )
  115.     {
  116.         case 'a':
  117.         case 'A':
  118.             if ( ap->devopen == 0 )
  119.             {
  120.                 e = RAMSDOpen(sPortA);
  121.                 if ( e != noErr )
  122.                 {
  123.                     printf("RAMSDOpen failed, e = %d\n",e);
  124.                     SysBeep(4);
  125.                     ExitToShell();
  126.                 }
  127.                 e = OpenDriver ("\p.AIn", &iref);
  128.                 if ( e != noErr) {
  129.                     printf("OpenDriver for AIn failed, e = %d\n",e);
  130.                     SysBeep (4);
  131.                     ExitToShell ();
  132.                 }
  133.                 e = OpenDriver ("\p.AOut", &oref);
  134.                 if ( e != noErr) {
  135.                     printf("OpenDriver for AOut failed, e = %d\n",e);
  136.                     SysBeep (4);
  137.                     CloseDriver (iref);
  138.                     ExitToShell ();
  139.                 }
  140.                 ap->portIn = AinRefNum;
  141.                 ap->portOut = AoutRefNum;
  142.                 ap->devopen = 1;
  143.             }
  144.             else
  145.             {
  146.                 printf("Device %c is already open.\n", ap->tty[0]);
  147.                 return(-1);
  148.             }
  149.             break;
  150.         
  151.         case 'b':
  152.         case 'B':
  153.             if ( ap->devopen == 0)
  154.             {
  155.                 e = RAMSDOpen(sPortB);
  156.                 if ( e != noErr )
  157.                 {
  158.                     printf("RAMSDOpen failed, e = %d\n", e);
  159.                     SysBeep(4);
  160.                     ExitToShell();
  161.                 }
  162.                 e = OpenDriver ("\p.BIn", &iref);
  163.                 if ( e != noErr) {
  164.                     printf("OpenDriver for BIn failed, e = %d\n", e);
  165.                     SysBeep (4);
  166.                     ExitToShell ();
  167.                 }
  168.                 e = OpenDriver ("\p.BOut", &oref);
  169.                 if ( e != noErr) {
  170.                     printf("Opendriver for Bout failed e = %d\n",e);
  171.                     SysBeep (4);
  172.                         CloseDriver (iref);
  173.                     ExitToShell ();
  174.                 }
  175.                 ap->portIn = BinRefNum;
  176.                 ap->portOut = BoutRefNum;
  177.                 ap->devopen = 1;
  178.             }
  179.             else
  180.             {
  181.                 printf("Device %c is already open.\n", ap->tty[0] );
  182.                 return(-1);
  183.             }
  184.             break;
  185.         
  186.         default:
  187.             printf("Unknown device %c, could not configure port,\n", ap->tty);
  188.             return(-1);
  189.     }
  190.         
  191.         
  192.     store = &Store_input[dev];
  193.     store->head =  store->store;
  194.     store->tail = store->store;
  195.     store->amt = 0;
  196.     e = SerSetBuf( ap->portIn, Recv_buf, MAX_STORE);
  197.     if ( e != noErr) {
  198.         printf("asy_init: SerSetBuf error on %d\n", ap->portIn);
  199.         SysBeep (4);
  200.         CloseDriver (iref);
  201.         ExitToShell ();
  202.     }
  203.     SerSetBuf( ap->portOut, Send_buf, MAX_STORE);
  204.     if ( e != noErr) {
  205.         printf("asy_init: SerSetBuf error on %d\n", ap->portOut);
  206.         SysBeep (4);
  207.         CloseDriver (iref);
  208.         ExitToShell ();
  209.     }
  210.     slipisopen = 1;
  211.     return (0);
  212. }
  213.  
  214. int
  215. asy_stop(interface)
  216. struct interface *interface;
  217. {
  218.     register struct asy *ap;
  219.     int ref;
  220.     
  221.     ap = &asy[interface->dev];
  222.  
  223.     if (slipisopen)
  224.     {
  225.         MacSer.ioActCount = 0;
  226.         MacSer.ioRefNum = ap->portIn;
  227.         MacSer.ioCompletion = 0;
  228.         MacSer.ioBuffer = ap->recv_buf;
  229.         MacSer.ioReqCount = 0;
  230.         MacSer.ioPosMode = 1;
  231.         (void) PBKillIO(&MacSer, FALSE);
  232.         
  233.         MacSer.ioActCount = 0;
  234.         MacSer.ioRefNum = ap->portOut;
  235.         MacSer.ioCompletion = 0;
  236.         MacSer.ioBuffer = ap->recv_buf;
  237.         MacSer.ioReqCount = 0;
  238.         MacSer.ioPosMode = 1;
  239.         (void) PBKillIO(&MacSer, FALSE);
  240.  
  241.         FSClose(ap->portIn);
  242.         FSClose(ap->portOut);
  243.         if ( ap->portIn = AinRefNum)
  244.         {
  245.             OpenDriver("\p.Ain", &ref);
  246.             OpenDriver("\p.Aout", &ref);
  247.         }
  248.         else
  249.         {
  250.             OpenDriver("\p.Bin", &ref);
  251.             OpenDriver("\p.Bout", &ref);
  252.         }
  253.         
  254.         slipisopen = 0;
  255.     }
  256. }
  257.  
  258. /* Asynchronous line I/O control */
  259. asy_ioctl(interface,argc,argv)
  260. struct interface *interface;
  261. int argc;
  262. char *argv[];
  263. {
  264.     if(argc < 1){
  265.         printf("%d\r\n",asy[interface->dev].speed);
  266.         return 0;
  267.     }
  268.     return asy_speed(interface->dev,atoi(argv[0]));
  269. }
  270.  
  271.  
  272. /* Set asynch line speed */
  273. int
  274. asy_speed(dev,speed)
  275. int dev;
  276. int speed;
  277. {
  278.     OsErr e;
  279.     int serialconfig;
  280.     SerShk    HandShake;
  281.     struct asy *ap;
  282.  
  283.     
  284.     ap = &asy[dev];
  285.  
  286.     if(speed == 0 || dev >= nasy)
  287.         return(-1);
  288.     
  289. #ifdef DEBUG
  290.     printf("asy_speed: Setting speed for device %d to %d\n",dev, speed);
  291. #endif
  292.     asy[dev].speed = speed;
  293.  
  294.     switch(speed)
  295.     {
  296.         case 300:
  297.             serialconfig = baud300;
  298.             break;
  299.         case 600:
  300.             serialconfig = baud600;
  301.             break;
  302.         case 1200:
  303.             serialconfig = baud1200;
  304.             break;
  305.         case 1800:
  306.             serialconfig = baud1800;
  307.             break;
  308.         case 2400:
  309.             serialconfig = baud2400;
  310.             break;
  311.         case 3600:
  312.             serialconfig = baud3600;
  313.             break;
  314.         case 4800:
  315.             serialconfig = baud4800;
  316.             break;
  317.         case 7200:
  318.             serialconfig = baud7200;
  319.             break;
  320.         case 9600:
  321.             serialconfig = baud9600;
  322.             break;
  323.         case 19200:
  324.             serialconfig = baud19200;
  325.             break;
  326.         case (long)57600:
  327.             serialconfig = baud57600;
  328.             break;
  329.         default:
  330.             printf("asy_speed: Unknown speed (%ld)\n", speed);
  331.             break;
  332.     }
  333. /*    
  334.     printf("serialconfig = %d\n", serialconfig);
  335. */
  336.     serialconfig |= (stop10|noParity|data8);
  337.  
  338.  
  339.     e = SerReset( ap->portIn, serialconfig);
  340.     if ( e != noErr) {
  341.         printf("asy_speed: could not set config for %d\n", ap->portIn);
  342.         SysBeep (4);
  343.         CloseDriver (iref);
  344.         ExitToShell ();
  345.     }
  346.     
  347.     bzero(&HandShake, sizeof (SerShk));
  348.     e = SerHShake(ap->portIn, &HandShake);
  349.     if ( e != noErr) {
  350.         printf("asy_speed: could not set handshake for %d\n", ap->portIn);
  351.         SysBeep (4);
  352.         CloseDriver (iref);
  353.         ExitToShell ();
  354.     }
  355.     
  356.     e = SerReset( ap->portOut, serialconfig);
  357.     if ( e != noErr) {
  358.         printf("asy_speed: could not set config for %d\n", ap->portOut);
  359.         SysBeep (4);
  360.         ExitToShell ();
  361.     }
  362.     bzero(&HandShake, sizeof (SerShk));
  363.     e = SerHShake(ap->portOut, &HandShake);
  364.     if ( e != noErr) {
  365.         printf("asy_speed: could not set handshake for %d\n", ap->portOut);
  366.         SysBeep (4);
  367.         CloseDriver (iref);
  368.         ExitToShell ();
  369.     }
  370.     /*
  371.     printf("asy_speed: completed.\n");
  372.     */
  373.     return(0);
  374.  
  375. }
  376. /* Send a buffer to serial transmitter */
  377. asy_output(dev,buf,cnt)
  378. unsigned dev;
  379. char *buf;
  380. unsigned short cnt;
  381. {
  382.     register struct asy *ap;
  383.     long amount = (long)cnt;
  384.     ap = &asy[dev];
  385.     /*
  386.     printf("asy_output called. dev = %x, cnt = %d\n", dev, cnt);
  387.     */
  388.     if(dev >= nasy)
  389.         return(-1);
  390.     FSWrite(ap->portOut,&amount, buf);
  391.     return(0);
  392.  
  393. }
  394.  
  395. /*
  396.  * Receive characters from asynch line
  397.  * Returns count of characters read
  398.  */
  399.  
  400. unsigned
  401. asy_recv(dev,buf,cnt)
  402. int dev;
  403. char *buf;
  404. unsigned cnt;
  405. {
  406.     long amount[8];
  407.     int tot = 0;
  408.     struct Store_input *store;
  409.     char store_it[MAX_STORE];
  410.     int got = 0;
  411.     int tt;
  412.      struct asy *ap;
  413.  
  414. #ifdef DEBUG
  415. printf("asy_recv: dev = %d\n", dev);    
  416. #endif
  417.  
  418.     if ( dev > nasy )
  419.     {
  420.         printf("Error on asy_recv. dev = %d, max = %d\n", dev, nasy);
  421.         return(-1);
  422.     }
  423.  
  424.     ap = &asy[dev];
  425.  
  426.     store = &Store_input[dev];        /* point to current */
  427.  
  428. /* printf("asy_recv: want %d, buffer has %d bytes\n", cnt, store->amt);    */
  429.  
  430.     if ( cnt > 0 && store->amt > 0)
  431.     {
  432.         tt = min(cnt , store->amt);
  433.         tt = min(tt,    MAX_STORE);
  434.         got = 0;
  435.         
  436. /*    printf ( "(if cnt = %d && store->amt = %d) tt = %d\n", cnt, store->amt, tt); */
  437.  
  438.         while ( tt-- > 0)
  439.         {
  440.             buf[got++] = *store->tail++;
  441.             if ( store->tail >= &store->store[MAX_STORE])
  442.             {
  443.                 store->tail = store->store;    /* wrap around */
  444.             }
  445.             if ( got >= cnt )
  446.                 break;
  447.         }
  448.         store->amt -= got;
  449.     /* printf("got = %d\n", got); */
  450.         return( got );
  451.     }
  452.     else if ( cnt == 0 )
  453.     {
  454.         return(0);
  455.     }
  456.     
  457.     Status( ap->portIn, 2, &amount[0]);
  458.     if (  amount[0] > 0L) 
  459.     {
  460.         MacSer.ioRefNum = ap->portIn;
  461.         MacSer.ioCompletion = 0;
  462.         MacSer.ioBuffer = ap->recv_buf;
  463.         MacSer.ioReqCount = (amount[0] < MAX_STORE) ? amount[0] : MAX_STORE;
  464.         MacSer.ioPosMode = 1;
  465.         tot = PBRead(&MacSer, FALSE);
  466.         if ( MacSer.ioResult != noErr)
  467.         {
  468.             printf("asy_read: read failed.\n");
  469.         }
  470.         tt = MacSer.ioActCount;
  471.         got = 0;
  472.         while (tt-- > 0)
  473.         {
  474.             *store->head++ = ap->recv_buf[got++];
  475.             if ( store->head == &store->store[MAX_STORE] )
  476.             {
  477.                 /* printf("xx got wrap\n"); */
  478.                 store->head = store->store;
  479.             }
  480.             store->amt++;
  481.         }
  482.         if ( cnt > 0 && store->amt > 0)
  483.         {
  484.             tt = min(cnt , store->amt);
  485.             tt = min(tt,    MAX_STORE);
  486.             got = 0;
  487.         
  488. /*    printf ( "(if cnt = %d && store->amt = %d) tt = %d\n", cnt, store->amt, tt); */
  489.  
  490.             while ( tt-- > 0)
  491.             {
  492.                 buf[got++] = *store->tail++;
  493.                 if ( store->tail >= &store->store[MAX_STORE])
  494.                 {
  495.                     store->tail = store->store;    /* wrap around */
  496.                 }
  497.                 if ( got >= cnt )
  498.                     break;
  499.             }
  500.             store->amt -= got;
  501.             return( got );
  502.         }
  503.         return ( 0 );
  504.     }
  505.     return (got);
  506.  
  507. }
  508.  
  509. /*
  510.  * dir: Create a directory listing in a temp file and return the resulting file
  511.  * descriptor. If full == 1, give a full listing; else if full ==3, output to console,
  512.  * else return just a list
  513.  * of names.
  514.  *
  515.  */
  516. FILE *
  517. dir(path,full)
  518. char *path;
  519. int full;
  520. {
  521.     WDPBRec Mydisk;
  522.     FILE *fp;
  523.     CInfoPBRec Everything;
  524.     OSErr e;
  525.     char working_vol[255];
  526.     char working_dir[255];
  527.     char holding_file[255];
  528.     char *PtoCstr(), *ctime();
  529.     char *ptr;
  530.     char buff[255];
  531.  
  532.  
  533.     bzero(&Mydisk, sizeof(WDPBRec));
  534.     bzero(&Everything, sizeof(Everything));
  535.  
  536.     errno = 0;
  537.     if ( full < 3)
  538.     {
  539.         if ( ( fp = fopen("dir.temp", "w")) == NULL)
  540.         {
  541.             printf("Open failed, errno = %d\n",errno);
  542.             return((FILE *)NULL);
  543.         }
  544.     }
  545.     else
  546.     {
  547.         fp = stdout;
  548.     }
  549.     
  550.     Mydisk.ioWDProcID = 0L;
  551.     Mydisk.ioWDDirID = 0L;
  552.     Mydisk.ioVRefNum = 0;
  553.     Mydisk.ioWDVRefNum = 0;
  554.     Mydisk.ioNamePtr = (StringPtr)working_vol;
  555.     if ( path[0] == '\0' )
  556.     {
  557.         path = ":";
  558.     }
  559.     MoveIt(Mydisk.ioNamePtr, path);
  560.     
  561.     e = PBOpenWD( &Mydisk, FALSE);
  562.     
  563.     if ( e != noErr )
  564.     {
  565.         printf("ERROR in PWOpenWD\n");
  566.         if ( full < 3)
  567.         {
  568.             fclose(fp);
  569.         }
  570.         return((FILE *)NULL);
  571.     }
  572.  
  573.     Everything.hFileInfo.ioNamePtr = (StringPtr)holding_file;
  574.     Everything.hFileInfo.ioVRefNum = Mydisk.ioVRefNum;
  575.     sprintf(Everything.hFileInfo.ioNamePtr, "\p");
  576.     Everything.hFileInfo.ioFDirIndex = 1;
  577.     Everything.hFileInfo.ioDirID = Mydisk.ioWDDirID;
  578.     Everything.hFileInfo.ioCompletion = 0;
  579.  
  580.     while( (e = PBGetCatInfo( &Everything, FALSE)) != fnfErr)
  581.     {
  582.         if ( e == noErr )
  583.         {
  584.             if( full == 0)
  585.             {
  586.                 fprintf(fp, "%s\n",
  587.                      PtoCstr(Everything.hFileInfo.ioNamePtr));
  588.             }
  589.             else
  590.             {
  591.                 
  592.                 ptr = ctime((long *)&Everything.hFileInfo.ioFlCrDat);
  593.                 ptr +=3;
  594.                 ptr[strlen(ptr)-9] = '\0';
  595.                 fprintf(fp,"%c  %7ld  %s  %s\n",
  596.                     (Everything.hFileInfo.ioFlAttrib & (1<<4))?'d':'-',
  597.                     Everything.hFileInfo.ioFlLgLen +
  598.                      Everything.hFileInfo.ioFlRLgLen, ptr,
  599.                     PtoCstr(Everything.hFileInfo.ioNamePtr));
  600.             }
  601.             
  602.             Everything.hFileInfo.ioFlLgLen = 0;
  603.             Everything.hFileInfo.ioFDirIndex++;
  604.  
  605.         }
  606.         else
  607.         {
  608.             PBCloseWD(&Mydisk, FALSE);
  609.             if ( full < 3 )
  610.             {
  611.                 fclose(fp);
  612.                 fp = fopen("dir.temp", "r");
  613.                 unlink("dir.temp");
  614.                 return(fp);
  615.             }
  616.         }
  617.         Everything.hFileInfo.ioDirID = Mydisk.ioWDDirID;
  618.     }
  619.     PBCloseWD(&Mydisk, FALSE);
  620.     if ( full < 3)
  621.     {
  622.         fclose(fp);
  623.         fp = fopen("dir.temp", "r");
  624.         unlink("dir.temp");
  625.     }
  626.     return(fp);
  627. }
  628.  
  629. /*
  630.  * MoveIt: this is like a bcopy, but uses pascal string type
  631.  * of data.
  632.  */
  633.  
  634. MoveIt(to,from)
  635. char *to, *from;
  636. {
  637.     int size;
  638.  
  639.     bzero(to, 3);
  640.     to[0] = size = strlen(from);
  641.     if ( size <= 0)
  642.     {
  643.         printf("MoveIt: size <= 0 (%d\n", size);
  644.         return;
  645.     }
  646.     to++;
  647.     while( size-- )
  648.         *to++ = *from++;    
  649. }
  650.  
  651. /*
  652.  * mktemp: make temporary file and return a pointer to it.
  653.  */
  654.  
  655. char *mktemp(ff)
  656. char *ff;
  657. {
  658.     long tt;
  659.     char *ptr;
  660.     if ( ( ptr = index(ff, 'X') ) == NULL)
  661.     {
  662.         ptr = ff;
  663.     }
  664.     tt = TickCount();
  665.     tt &= 0xffffffff;
  666.     sprintf(ptr, "%ld", tt);
  667.     return(ff);
  668. }
  669.  
  670. /*
  671.  * index: find the first char in string that matches arg.  LSC does not
  672.  * have this routine.
  673.  */
  674.  
  675. char *index(str, find)
  676. char *str;
  677. char find;
  678. {
  679.     char *strchr();
  680.  
  681.     return(strchr(str, find));
  682. }
  683.  
  684.  
  685. static WDPBRec Mydisk;
  686. static CInfoPBRec Everything;
  687. static IsOpen = 0;    /* tells me that the file is open */
  688. static char *name_ptr;
  689. static char working_dir[255];
  690. static char holding_file[255];
  691. static     char working_vol[255];
  692.  
  693. /*
  694.  * filedir: find a file that matches the dest arg
  695.  */
  696.  
  697. char *filedir(path,value,dest)
  698. char *path;
  699. int   value;
  700. char *dest;
  701. {
  702.  
  703.     FILE *fp;
  704.     OSErr e;
  705.     char *PtoCstr(), *ctime();
  706.     char *ptr;
  707.     char buff[255];
  708.     char *rindex();
  709.     char keep;
  710.     
  711.     dest[0] = '\0';
  712.     if ( IsOpen == 0 && value == 0)
  713.     {
  714.         Mydisk.ioWDProcID = 0L;
  715.         Mydisk.ioWDDirID = 0L;
  716.         Mydisk.ioVRefNum = 0;
  717.         Mydisk.ioWDVRefNum = 0;
  718.         Mydisk.ioNamePtr = (StringPtr)working_vol;
  719.         if ( path[0] == '\0' )
  720.         {
  721.             path = ":";
  722.         }
  723.         if ( (ptr = rindex(path, ':')) != NULL)
  724.         {
  725.             keep = *ptr;
  726.             *ptr = '\0';
  727.             MoveIt(Mydisk.ioNamePtr, path);
  728.             *ptr = keep;
  729.         }
  730.         else
  731.         {
  732.             MoveIt(Mydisk.ioNamePtr, path);
  733.         }
  734.         if ( ( name_ptr = rindex( path, '.')) != NULL)
  735.         {
  736.             name_ptr++;
  737.         }
  738.         else
  739.         {
  740.             name_ptr = "";
  741.         }
  742.     }
  743.     
  744.     e = PBOpenWD( &Mydisk, FALSE);
  745.     
  746.     if ( e != noErr )
  747.     {
  748.         printf("ERROR in PWOpenWD\n");
  749.         IsOpen = 0;
  750.         return( (char *)-1);
  751.     }
  752.         
  753.         /* mark as open */
  754.         
  755.     IsOpen = 1;
  756.  
  757.     /*
  758.      * set up for getting the info from the directory
  759.      */
  760.      
  761.     Everything.hFileInfo.ioNamePtr = (StringPtr)holding_file;
  762.     Everything.hFileInfo.ioVRefNum = Mydisk.ioVRefNum;
  763.     sprintf(Everything.hFileInfo.ioNamePtr, "\p");
  764.     
  765.     if ( value == 0 )
  766.     {
  767.         Everything.hFileInfo.ioFDirIndex = 1;
  768.     }
  769.     
  770.     Everything.hFileInfo.ioDirID = Mydisk.ioWDDirID;
  771.     Everything.hFileInfo.ioCompletion = 0;
  772.  
  773.     
  774.     while( (e = PBGetCatInfo( &Everything, FALSE)) != fnfErr)
  775.     {
  776.         if ( e == noErr )
  777.         {
  778.             
  779.             PtoCstr(Everything.hFileInfo.ioNamePtr);
  780.             if ( ( ptr = index( Everything.hFileInfo.ioNamePtr, '.')) != NULL) 
  781.             {
  782.                 ptr++;
  783.                 if ( strncmp(ptr, name_ptr, strlen(name_ptr)) == 0) 
  784.                 {
  785.                     sprintf(dest,"%s", Everything.hFileInfo.ioNamePtr);
  786.                     Everything.hFileInfo.ioFDirIndex++;
  787.                     PBCloseWD(&Mydisk, FALSE);
  788.                     return;
  789.                 }
  790.             }
  791.             Everything.hFileInfo.ioFlLgLen = 0;
  792.             Everything.hFileInfo.ioFDirIndex++;
  793.             Everything.hFileInfo.ioDirID = Mydisk.ioWDDirID;
  794.  
  795.         }
  796.         else
  797.         {
  798.             IsOpen = 0;
  799.             PBCloseWD(&Mydisk, FALSE);
  800.             return(0);
  801.         }
  802.         Everything.hFileInfo.ioDirID = Mydisk.ioWDDirID;
  803.     }
  804.     IsOpen = 0;
  805.     PBCloseWD(&Mydisk, FALSE);
  806. }
  807.  
  808. /*
  809.  * rindex: find the last char in string which matches arg.  LSC does not
  810.  * have this routine.
  811.  */
  812.  
  813. char *rindex(str, c)
  814. char *str, c;
  815. {
  816.     char *strrchr();
  817.     return(strrchr(str, c));
  818. }
  819.  
  820. int asy_attach();
  821. extern struct cmds attab[];
  822.  
  823. /*
  824.  * eihalt: normally this would wait for an interrupt, but it doesn't here.
  825.  * this will check for the button.  If the button has been depressed, the process
  826.  * exits
  827.  */
  828.  
  829. eihalt()
  830. {
  831.     if (Button())
  832.     {
  833.         iostop();
  834.         exit(0);
  835.     }
  836.     return(0);
  837. }
  838.  
  839. /*
  840.  * kbread: see if a char is available on keyboard, if so go get it.
  841.  */
  842. kbread()
  843. {
  844.     int    mask;
  845.     int    ok;
  846.     char    c = -1;
  847.     if( kbhit() ){
  848.         c = getch();
  849.     }
  850.     return(c);
  851. }
  852.  
  853. /*
  854.  * clksec: return the amount of time in secs.
  855.  */
  856.  
  857. int32
  858. clksec()
  859. {
  860.     return(time(NULL));
  861. }
  862.  
  863. /*
  864.  * tmpfile: create a temporary file.  Remember it so we can delete it later because
  865.  * the mac does not allow the file to be deleted when it is open.
  866.  */
  867.  
  868. FILE *
  869. tmpfile()
  870. {
  871.     FILE *tmp;
  872.     char *mktemp();
  873.     char *ptr = "SMTPXXXXXXXX";
  874.     char *name;
  875.     struct RemoveIt *rptr;
  876.     
  877.     name = mktemp(ptr);
  878.     if ( ( tmp = fopen(name, "w+") ) == NULL)
  879.     {
  880.         printf("tmpfile: counld not create temp file. (%s)\n", name);
  881.         return(NULL);
  882.     }
  883.     rptr = Head;
  884.     while(rptr->next != NULL )
  885.     {
  886.         rptr = rptr->next;
  887.     }
  888.     
  889.     if ( (rptr->next = (struct RemoveIt *)malloc(sizeof (struct RemoveIt)) ) == NULL)
  890.     {
  891.         printf("Could not allocate memory for structure RemoveIt\n");
  892.         return(tmp);
  893.     }
  894.     rptr = rptr->next;
  895.     rptr->next = NULL;
  896.     if ( (rptr->name_ptr = malloc(strlen(name)+1) ) == NULL)
  897.     {
  898.         printf("Could not allocate memory for %s\n", name);
  899.         return(tmp);
  900.     }
  901.     
  902.     sprintf(rptr->name_ptr, "%s", name);
  903.     return ( tmp );
  904. }
  905.  
  906. /* restore: stub */
  907. restore()
  908. {}
  909.  
  910. /* stxrdy: stub */
  911. stxrdy()
  912. {return(1);}
  913.  
  914. /* disable: stub */
  915. disable()
  916. {}
  917.  
  918. /* memstat: stub */
  919. memstat()
  920. {
  921.     return(0);
  922. }
  923.  
  924. /* checks the time then ticks and updates ISS */
  925. static int32 clkval = 0;
  926. void
  927. check_time()
  928. {
  929.     int32 iss();
  930.     int32 clksec();
  931.  
  932.     if(clkval != clksec()){
  933.         clkval = clksec();
  934.         tick();
  935.         (void)iss();
  936.     }
  937. }
  938.  
  939. /*
  940.  * Access: check the file for access permission.  Some of this has to be faked on
  941.  * a Mac, since it does not have access bits.
  942.  */
  943.  
  944. access(str, perm)
  945.  char *str;
  946.  int perm;
  947. {
  948.     FILE *fptr;
  949.     CInfoPBRec    paramBlock;
  950.     StringPtr CtoPstr();
  951.     OSErr e;
  952.     
  953.     paramBlock.hFileInfo.ioCompletion = 0;
  954.     paramBlock.hFileInfo.ioVRefNum = 0;
  955.     paramBlock.hFileInfo.ioFDirIndex = 0;
  956.     paramBlock.hFileInfo.ioDirID = 0;
  957.     paramBlock.hFileInfo.ioNamePtr = CtoPstr(str);
  958.  
  959.     /*
  960.      * Get info on file named in ioNamePtr
  961.      */
  962.      
  963.     e = PBGetCatInfo( ¶mBlock, FALSE);
  964.     PtoCstr(str);
  965.     
  966.     /*
  967.      * if there is an error then find out if the file is present.  If so
  968.      * see if user wants to create the file
  969.      */
  970.      
  971.     if ( e != noErr )
  972.     {
  973.         if ( ( e == fnfErr) && (perm == 2))
  974.         {
  975.             return(0);
  976.         }
  977.         else
  978.         {
  979.             return(1);
  980.         }
  981.     }
  982.     /*
  983.      * check to see if the file is locked or open.  refuse it if it is.
  984.      */
  985.      
  986.     if ( (BitTst( ¶mBlock.hFileInfo.ioFlAttrib, 0) 
  987.             || BitTst( ¶mBlock.hFileInfo.ioFlAttrib, 7) )
  988.             && perm == 4 )
  989.     {
  990.         return(1);
  991.     }
  992.     else
  993.         return(0);
  994.     
  995. }
  996.  
  997. /*
  998.  * Bzero: zero out a buffer
  999.  */
  1000.  
  1001. bzero(str, cnt)
  1002. char *str;
  1003. int    cnt;
  1004. {
  1005.     while(cnt-- != 0)
  1006.         *str++ = '\0';
  1007. }
  1008.  
  1009. /*
  1010.  * memcmp: compare memory
  1011.  */
  1012.  
  1013. memcmp(str1, str2, len)
  1014. char *str1, *str2;
  1015. int len;
  1016. {
  1017.     return( strncmp(str1, str2, len));
  1018. }
  1019.  
  1020. /* 
  1021.  * memset: set a value in memory
  1022.  */
  1023.  
  1024. memset(str, value, len)
  1025. char *str;
  1026. int value, len;
  1027. {
  1028.     while ( len-- != 0)
  1029.     {
  1030.         *str++ = value;
  1031.     }
  1032. }
  1033.  
  1034. /*
  1035.  * memcpy: copy from one place to another
  1036.  */
  1037.  
  1038. memcpy(str1, str2, len)
  1039. char *str1, *str2;
  1040. int len;
  1041. {
  1042.     while ( len-- != 0)
  1043.         *str1++ = *str2++;
  1044. }
  1045.  
  1046. /* List directory to console */
  1047. dodir(argc,argv)
  1048. int argc;
  1049. char *argv[];
  1050. {
  1051.     if ( argc > 2)
  1052.         dir( argv[1], 3);
  1053.     else
  1054.         dir(":",3);
  1055.     return 0;
  1056. }
  1057.  
  1058. /*
  1059.  * docd: perform a change directory
  1060.  */
  1061.  
  1062. docd(argc, argv)
  1063. int argc;
  1064. char *argv[];
  1065. {
  1066.     char dirname[128],*getwd();
  1067.  
  1068.     if(argc > 1){
  1069.         if(chdir(argv[1]) == -1){
  1070.             printf("Can't change directory\n");
  1071.             return 1;
  1072.         }
  1073.     }
  1074.     if(getwd(dirname,0) != NULLCHAR){
  1075.         printf("%s\n",dirname);
  1076.     }
  1077.     return 0;
  1078. }
  1079.  
  1080. chdir( path )
  1081. char * path;
  1082. {
  1083.     WDPBRec    Mydisk;
  1084.     int err;
  1085.     register char * cp;
  1086.     char *index();
  1087.     OSErr e;
  1088.  
  1089. #ifdef DEBUG
  1090.     printf("Entering chdir\n");
  1091. #endif
  1092.  
  1093.     Mydisk.ioWDProcID = 0L;
  1094.     Mydisk.ioWDDirID = 0L;
  1095.      Mydisk.ioVRefNum = 0;
  1096.     printf("chdir: path = %s\n", path);
  1097.     Mydisk.ioWDVRefNum = 0;
  1098.     CtoPstr(path);
  1099.     Mydisk.ioNamePtr = path;
  1100. #ifdef DEBUG
  1101.     printf("chdir: calling PBOpenWD.\n");
  1102.     printf("Mydisk.ioVRefNum = %d\n", Mydisk.ioVRefNum);
  1103. #endif    
  1104.     e = PBOpenWD( &Mydisk, FALSE);
  1105.     
  1106.     if ( e != noErr )
  1107.     {
  1108.         PtoCstr(path);
  1109.         return(-1);
  1110.     }
  1111.     
  1112.     if ( ( e = PBHSetVol( &Mydisk, FALSE) ) != noErr)
  1113.     {
  1114.         PtoCstr(path);
  1115.         return(-1);
  1116.     }
  1117.  
  1118.     PtoCstr(path);
  1119.     return 0;
  1120.  
  1121. }
  1122.  
  1123. char *getwd()
  1124. {
  1125.     return(NULL);
  1126. }
  1127.  
  1128. /*
  1129.  * doshell:  execute a shell for the user
  1130.  */
  1131.  
  1132. doshell()
  1133. {
  1134.     printf("SHELL is not implemented.\n");
  1135. }
  1136.  
  1137. char *timez = "CST";
  1138.  
  1139. char *getenv(str)
  1140. char *str;
  1141. {
  1142.     return(timez);
  1143. }
  1144.